from django.conf import settings
from rest_framework import serializers
from .models import Category, Tag, Article, ArticleImage,Topic, Like, Collection
from ctbloge.apps.comments.serializers import CommentSerializer
from django.contrib.contenttypes.models import ContentType
import datetime
class CategorySerializer(serializers.ModelSerializer):
    parent = serializers.SlugRelatedField(
        slug_field='slug',
        queryset=Category.objects.all(),
        allow_null=True,
        required=False
    )
    is_root = serializers.BooleanField(read_only=True)
    children = serializers.SerializerMethodField()
    url = serializers.SerializerMethodField()

    created_date = serializers.DateTimeField(format='%Y年%m月%d日 %H:%M')

    class Meta:
        model = Category
        fields = [
            'id', 'name', 'slug','url',  'parent', 'description','cover',
            'is_root', 'children', 'created_date'
        ]
        read_only_fields = ['is_root', 'children', 'created_date']

    validators = [
        serializers.UniqueTogetherValidator(
            queryset=Category.objects.all(),
            fields=['name', 'parent'],
            message="同目录下分类名称必须唯一"
        )
    ]
    def get_children(self, obj):
        return CategorySerializer(obj.children.all(), many=True, context=self.context).data

    def get_url(self, obj):
        return obj.get_absolute_url()
class CategoryListSerializer(CategorySerializer):
    article_count = serializers.SerializerMethodField()
    class Meta:
        model = Category
        fields = ['id', 'name', 'url', 'parent', 'description', 'is_root', 'article_count','created_date']
        read_only_fields = ['is_root', 'created_date']
    def get_article_count(self, obj):
        return obj.articles.filter(status='published').count()
class CategoryArticleInfoSerializer(CategorySerializer):
    articles = serializers.SerializerMethodField()
    article_count = serializers.SerializerMethodField()
    class Meta:
        model = Category
        fields = ['id', 'name', 'url', 'description','cover', 'article_count', 'articles', 'created_date']
        read_only_fields = ['articles', 'created_date']

    def get_articles(self, obj):#只需要文章的id和标题
        return [{
            'id': article.id,
            'title': article.title,
            'url': article.get_absolute_url(),
            'topic': article.topics.name if article.topics else None,
        } for article in obj.articles.filter(status='published')]

    def get_article_count(self, obj):
        return obj.articles.filter(status='published').count()

class TagSerializer(serializers.ModelSerializer):
    article_count = serializers.SerializerMethodField()
    class Meta:
        model = Tag
        fields = '__all__'
        extra_kwargs = {
            'color_code': {'required': False}
        }

    def get_article_count(self, obj):#获取标签下的已发表文章数量
        return obj.articles.filter(status='published').count()

class ArticleImageSerializer(serializers.ModelSerializer):
    class Meta:
        model = ArticleImage
        fields = ['image', 'order']
class ArticleSerializer(serializers.ModelSerializer):
    content_type = serializers.SerializerMethodField()

    url = serializers.SerializerMethodField()
    # 获取分类名称
    category_name = serializers.CharField(source='category.name', read_only=True)
    #获取专题名称
    topic_name = serializers.CharField(source='topics.name', read_only=True)
    #获取作者头像和昵称
    #格式化时间
    publish_date = serializers.DateTimeField(format='%Y-%m-%d')
    created_date = serializers.DateTimeField(format='%Y-%m-%d')
    tags = serializers.SerializerMethodField()
    like_count = serializers.SerializerMethodField()
    collect_count = serializers.SerializerMethodField()
    images = ArticleImageSerializer(many=True, read_only=True)
    class Meta:
        model = Article
        fields = "__all__"
        extra_kwargs = {
            'content': {'allow_blank': True}
        }

    def get_url(self, obj):#获取文章详情页url
        return obj.get_absolute_url()
    def get_tags(self, obj):#获取标签id，name，color
        return [{'id': tag.id, 'name': tag.name, 'color': tag.color_code} for tag in obj.tags.all()]

    def validate(self, data):
        publish_date = data.get('publish_date')
        if 'slug' in data and publish_date is not None:  # 显式检查非 None
            # 确保 publish_date 是日期类型（防御非法类型输入）
            if not isinstance(publish_date, (datetime.date, datetime.datetime)):
                raise serializers.ValidationError("Invalid publish_date format")

            qs = Article.objects.filter(
                slug=data['slug'],
                publish_date__date=publish_date.date()  # 确保调用前对象有效
            )
            if self.instance:
                qs = qs.exclude(pk=self.instance.pk)
            if qs.exists():
                raise serializers.ValidationError("相同发布日期下已存在该 URL 标识的文章")
        return data

    def create(self, validated_data):
        """自动设置作者"""
        validated_data['author'] = self.context['request'].user
        return super().create(validated_data)

    def get_content_type(self, obj):
        return ContentType.objects.get_for_model(obj.__class__).id
    def get_like_count(self, obj):
        get_count = Like.objects.filter(content_type=ContentType.objects.get_for_model(Article), object_id=obj.id).count()
        return get_count
    def get_collect_count(self, obj):
        get_count = Collection.objects.filter(content_type=ContentType.objects.get_for_model(Article), object_id=obj.id).count()
        return get_count
class ArticleListSerializer(ArticleSerializer):

    #获取作者头像和昵称
    author = serializers.SerializerMethodField()

    """文章列表序列化器"""
    class Meta:
        model = Article
        fields = [
            'id', 'url', 'author', 'title', 'excerpt', 'category_name','topic_name','status', 'is_top', 'article_type', 'image', 'images',
             'like_count', 'views_count','comments_count','comments_count','collect_count','publish_date',
        ]
    def get_author(self, obj):
        return {
            'avatar': obj.author.avatar.url,
            'nickname': obj.author.nickname
        }
class ArticleDetailSerializer(ArticleSerializer):
    author = serializers.CharField(source='author.nickname', read_only=True)
    category = CategorySerializer(read_only=True)
    publish_date = serializers.DateTimeField(format='%Y年%m月%d日%H:%M')
    created_date = serializers.DateTimeField(format='%Y年%m月%d日%H:%M')
    content = serializers.SerializerMethodField()
    toc_html = serializers.SerializerMethodField()

    class Meta:
        model = Article
        fields = [
            'id', 'url', 'title', 'content','toc_html', 'author', 'topic_name', 'excerpt', 'article_type', 'image', 'images','status', 'is_commentable', 'is_top', 'like_count', 'views_count','collect_count','comments_count','created_date',  'publish_date','content_type', 'category','tags','comments']

    # 获取方法
    def get_content(self, obj):
        return obj.get_md()[0]

    def get_toc_html(self, obj):
        return obj.get_md()[1]
class ArticleSimpleSerializer(ArticleSerializer):
    images = ArticleImageSerializer(many=True, read_only=True)
    class Meta:
        model = Article
        fields = ['id', 'title', 'url','image','images']
class ArticlePrevNextSerializer(ArticleSerializer):
    class Meta:
        model = Article
        fields = ['id', 'title', 'url']
class ArchiveSerializer(serializers.ModelSerializer):#文章归档序列化器
    url = serializers.SerializerMethodField()
    class Meta:
        model = Article
        fields = ['id', 'url','title', 'publish_date']
    def get_url(self, obj):
        return obj.get_absolute_url()
class LikeSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Like
        fields = ['id', 'user', 'content_type', 'object_id', 'created_date']
        read_only_fields = ('created_date',)
        extra_kwargs = {
            'user': {'read_only': True}  # 禁止客户端修改用户字段
        }
class CollectionSerializer(serializers.ModelSerializer):
    user = serializers.HiddenField(default=serializers.CurrentUserDefault())

    class Meta:
        model = Collection
        fields = ['id', 'user', 'content_type', 'object_id', 'created_date']
        read_only_fields = ('created_date',)
        extra_kwargs = {
            'user': {'read_only': True}  # 禁止客户端修改用户字段
        }
class PersonalArticleSerializer(ArticleSerializer):
    images = ArticleImageSerializer(many=True, read_only=True)
    category = CategorySerializer(read_only=True)
    tags = TagSerializer(many=True, read_only=True)
    class Meta:
        model = Article
        fields = ['id', 'url', 'title', 'excerpt','content',  'category', 'topic_name','tags', 'status', 'is_top', 'article_type', 'image', 'images', 'created_date']
class TopicSerializer(serializers.ModelSerializer):#专题序列化器
    class Meta:
        model = Topic
        fields = '__all__'
class ArticleStatusSerializer(serializers.ModelSerializer):
    class Meta:
        model = Article
        fields = ['id', 'title', 'status']
#修改个人文章序列化器
class ArticleUpdateSerializer(serializers.ModelSerializer):
    images = ArticleImageSerializer(many=True, read_only=True)
    class Meta:
        model = Article
        fields = ['id', 'title', 'content', 'excerpt', 'category', 'tags',  'is_commentable', 'article_type', 'image', 'images',]
        extra_kwargs = {
            'content': {'allow_blank': True}
        }
#新建个人文章序列化器
class ArticleCreateSerializer(serializers.ModelSerializer):
    images = ArticleImageSerializer(many=True, read_only=True)
    class Meta:
        model = Article
        fields = ['id', 'title', 'content', 'excerpt', 'category', 'tags',  'is_commentable', 'article_type', 'image', 'images',]
        extra_kwargs = {
            'content': {'allow_blank': True}
        }
#图片上传序列化器
class ImageUploadSerializer(serializers.Serializer):
    image = serializers.ImageField(
        max_length=100,
        allow_empty_file=False,
        use_url=False
    )
    article_type = serializers.CharField(required=False)  # 用于区分上传类型

    def validate_image(self, value):
        if value.content_type not in settings.ALLOWED_IMAGE_TYPES:
            raise serializers.ValidationError("不支持的图片格式")
        if value.size > 5 * 1024 * 1024:  # 5MB限制
            raise serializers.ValidationError("图片大小不能超过5MB")
        return value